// BlankDetector.h
#ifndef BLANK_DETECTOR_H
#define BLANK_DETECTOR_H

#include <vector>
#include <cstdint>
#include <string>

struct Point {
    int x, y;
    Point(int x = 0, int y = 0) : x(x), y(y) {}
};

struct Color {
    uint8_t r, g, b, a;
    Color(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255) 
        : r(r), g(g), b(b), a(a) {}
    
    bool isNearlyEqual(const Color& other, uint8_t tolerance) const {
        return abs(r - other.r) <= tolerance &&
               abs(g - other.g) <= tolerance &&
               abs(b - other.b) <= tolerance;
    }
};

class BlankRegion {
public:
    std::vector<Point> pixels;
    Color dominantColor;
    int minX, minY, maxX, maxY;
    
    BlankRegion() : minX(INT_MAX), minY(INT_MAX), maxX(0), maxY(0) {}
    
    void addPixel(const Point& p, const Color& c) {
        pixels.push_back(p);
        if (pixels.size() == 1) {
            dominantColor = c;
        }
        updateBounds(p);
    }
    
    int getArea() const { return pixels.size(); }
    int getWidth() const { return maxX - minX + 1; }
    int getHeight() const { return maxY - minY + 1; }
    
private:
    void updateBounds(const Point& p) {
        minX = std::min(minX, p.x);
        minY = std::min(minY, p.y);
        maxX = std::max(maxX, p.x);
        maxY = std::max(maxY, p.y);
    }
};

enum class BlankLevel {
    NONE = 0,
    MINOR = 1,
    MODERATE = 2,
    SEVERE = 3,
    CRITICAL = 4
};

struct DetectionResult {
    BlankLevel blankLevel;
    std::vector<BlankRegion> blankRegions;
    double totalBlankRatio;
    int largestRegionSize;
    std::string description;
};

class BlankDetector {
public:
    static DetectionResult detect(const uint8_t* pixelData, 
                                 int width, int height, 
                                 int bytesPerPixel = 4);

private:
    struct Config {
        uint8_t colorTolerance;
        int minRegionSize;
        double minAreaRatio;
        int maxProcessWidth;
        int maxProcessHeight;
        double samplingRatio;
    };
    
    static Config getOptimalConfig(int width, int height);
    static std::vector<uint8_t> createSample(const uint8_t* data, 
                                            int width, int height, 
                                            int bytesPerPixel,
                                            int targetWidth, int targetHeight);
    static DetectionResult detectOnSample(const uint8_t* data, 
                                        int width, int height, 
                                        int bytesPerPixel,
                                        const Config& config);
    static BlankLevel calculateBlankLevel(const std::vector<BlankRegion>& regions,
                                        int totalPixels);
};

#endif